/***************************************************************************\
 * The Mattise Kernel														*
 * Copyright 2007 Matthew Iselin											*
 * Licensed under the GPL													*
 *																			*
 * vesa.cc																	*
 *																			*
 * VESA mode switcher.														*
 *																			*
\***************************************************************************/

#include <system.h>
#include <stdio.h>
#include <task.h>
#include <filesys.h>
#include <pm.h>
#include "memory.h"

// enters a VBE mode, returns the LFB address
uint_t EnterVesaMode( ushort_t xres, ushort_t yres, ushort_t bpp ) 
{
	// enter the wanted mode
	struct regs r;
	r.eax = xres;
	r.ebx = yres;
	r.ecx = bpp;
	
	// load the vbe switcher - TODO: this should be in a seperate file, in userland...
	FILE fp = fopen( "dr0/vbe.sys", "r" );
	
	// check if it is valid
	fread( (void*) 0x1000, 0, fp.size, fp );

	// --kmcguire: <processID=0=kernel>, <entry-address>, <priority=0=highest>, <user-stack>, <kernel-stack>, <user-code>, <user-data>,
	//			<cr3-physical-address=0=none-or-no-need-to-change>, <_cdelc argument count=0=none>, ... arguments = none
	//CreateThread( (unsigned int) nullproc, 1024, "System Idle Process", 1 );
	//sched_create_thread( 0, (unsigned long) &nullproc, 0, pm_alloc() + 4096, pm_alloc() + 4096, 0x8, 0x10, 0, 0x200, 0);	

	// start it
	//int p = CreateThread16bit( 0x1000, 1024, "VBE Mode Switcher", &r );
	sched_threadDescription td;
	memset(&td, 0, sizeof(td));
	td.entry = (ENTRYADDR)0x1000;
	td.contextId = 0;
	td.processId = 0;
	td.priority = 0;
	td.ustack = pm_allocEx(PM_LEGACY | PM_USED, PM_LEGACY, 0, 1) + 4096;
	td.kstack = pm_alloc() + 4096;
	td.cs = 0x00;
	td.ds = 0x10;
	td.eflags = SCHED_EFLAGS16;
	td.medaddr = 0;
	sched_create_thread(&td, 0);

	// wait for it
	//WaitUntilComplete( p );
	
	// get it's registers
	//GetRegs( p, &r );
	
	// close the file
	fclose( fp );
	
	// return the LFB address
	return r.ecx;
}
